/*
 * Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.huawei.cloudphone.service;

import static com.huawei.cloudphone.jniwrapper.JNIWrapper.CHANNEL;
import static com.huawei.cloudphone.jniwrapper.JNIWrapper.IMEDATA;

import android.os.IBinder;
import android.os.RemoteException;
import android.view.Surface;

import com.huawei.cloudphone.ICASAidlInterface;
import com.huawei.cloudphone.common.CASLog;
import com.huawei.cloudphone.common.CasConnectorInfo;
import com.huawei.cloudphone.common.CasParcelableMap;

/**
 * CASClient
 */
public class CASClient {

    /**
     * TAG:CASClient
     */
    private static final String TAG = "CASClient";
    /**
     * cas client
     */
    private static CASClient gCASClient = null;
    /**
     * cas interface
     */
    private ICASAidlInterface mCasInterface = null;

    public CASClient() {
        mCasInterface = null;
    }

    public static synchronized CASClient getInstance() {
        if (gCASClient == null) {
            gCASClient = new CASClient();
        }
        return gCASClient;
    }

    public void setInterface(ICASAidlInterface casInterface) {
        mCasInterface = casInterface;
    }

    public void init() {
        if (mCasInterface == null) {
            return;
        }
        try {
            mCasInterface.init();
        } catch (RemoteException e) {
            CASLog.e(TAG, "filed to call init");
        }
    }

    public void setEncryptData(String encryptData) {
        if (mCasInterface == null) {
            return;
        }
        try {
            mCasInterface.setEncryptData(encryptData);
        } catch (RemoteException e) {
            CASLog.e(TAG, "filed to call setEncryptData");
        }
    }

    public void setSurface(Surface suf) {
        if (mCasInterface == null) {
            return;
        }
        try {
            mCasInterface.setSurface(suf);
        } catch (RemoteException e) {
            CASLog.e(TAG, "filed to call setSurface");
        }
    }

    public boolean start(boolean isHome) {
        if (mCasInterface == null) {
            return false;
        }
        boolean ret;
        try {
            ret = mCasInterface.start(isHome);
        } catch (RemoteException e) {
            CASLog.e(TAG, "filed to call start");
            ret = false;
        }
        return ret;
    }

    public void stop(boolean isHome) {
        if (mCasInterface == null) {
            return;
        }
        try {
            mCasInterface.stop(isHome);
        } catch (RemoteException e) {
            CASLog.e(TAG, "filed to call stop");
        }
    }

    public void pause() {
        if (mCasInterface == null) {
            return;
        }
        try {
            mCasInterface.pause();
        } catch (RemoteException e) {
            CASLog.e(TAG, "filed to call pause");
        }
    }

    public void resume() {
        if (mCasInterface == null) {
            return;
        }
        try {
            mCasInterface.resume();
        } catch (RemoteException e) {
            CASLog.e(TAG, "filed to call resume");
        }
    }

    public boolean isConnect() {
        if (mCasInterface == null) {
            return false;
        }
        boolean ret;
        try {
            ret = mCasInterface.isConnect();
        } catch (RemoteException e) {
            CASLog.e(TAG, "filed to call isConnect");
            ret = false;
        }
        return ret;
    }

    public boolean reconnect() {
        if (mCasInterface == null) {
            return false;
        }
        boolean ret;
        try {
            ret = mCasInterface.reconnect();
        } catch (RemoteException e) {
            CASLog.e(TAG, "filed to call reconnect");
            ret = false;
        }
        return ret;
    }

    public void registerListener(IBinder listener) {
        if (mCasInterface == null) {
            return;
        }
        try {
            mCasInterface.registerListener(listener);
        } catch (RemoteException e) {
            CASLog.e(TAG, "filed to call registerListener");
        }
    }

    public void unregisterListener() {
        if (mCasInterface == null) {
            return;
        }
        try {
            mCasInterface.unregisterListener();
        } catch (RemoteException e) {
            CASLog.e(TAG, "filed to call unregisterListener");
        }
    }

    public boolean sendTouchEvent(int id, int action, int x, int y, int pressure, long time, int orientation, int height, int width) {
        if (mCasInterface == null) {
            return false;
        }
        boolean ret;
        try {
            ret = mCasInterface.sendTouchEvent(id, action, x, y, pressure, time, orientation, height, width);
        } catch (RemoteException e) {
            CASLog.e(TAG, "filed to call sendTouchEvent");
            ret = false;
        }
        return ret;
    }

    public boolean sendKeyEvent(int keycode, int action) {
        if (mCasInterface == null) {
            return false;
        }
        boolean ret;
        try {
            ret = mCasInterface.sendKeyEvent(keycode, action);
        } catch (RemoteException e) {
            CASLog.e(TAG, "filed to call sendKeyEvent");
            ret = false;
        }
        return ret;
    }

    public boolean sendMotionEvent(int materAxis, int materValue, int secondaryAxis, int secondaryValue) {
        if (mCasInterface == null) {
            return false;
        }
        boolean ret;
        try {
            ret = mCasInterface.sendMotionEvent(materAxis, materValue, secondaryAxis, secondaryValue);
        } catch (RemoteException e) {
            CASLog.e(TAG, "filed to call sendMotionEvent");
            ret = false;
        }
        return ret;
    }

    public void setCasConnectorInfo(CasConnectorInfo info) {
        if (mCasInterface == null) {
            return;
        }
        try {
            mCasInterface.setCasConnectorInfo(info);
        } catch (RemoteException e) {
            CASLog.e(TAG, "filed to call setCasConnectorInfo");
        }
    }

    public void setMediaConfig(CasParcelableMap mediaConfigMap) {
        if (mCasInterface == null) {
            return;
        }
        try {
            mCasInterface.setMediaConfig(mediaConfigMap);
        } catch (RemoteException e) {
            CASLog.e(TAG, "filed to call setMediaConfig");
        }
    }

    public int getState() {
        if (mCasInterface == null) {
            return 0;
        }
        int ret;
        try {
            ret = mCasInterface.getState();
        } catch (RemoteException e) {
            CASLog.e(TAG, "filed to call getState");
            ret = 0;
        }
        return ret;
    }

    public int getLag() {
        if (mCasInterface == null) {
            return 0;
        }
        int lag = 0;
        try {
            lag = mCasInterface.getLag();
        } catch (RemoteException e) {
            CASLog.e(TAG, "filed to call getLag");
            lag = 0;
        }
        return lag;
    }

    public boolean startJniRecv() {
        if (mCasInterface == null) {
            return false;
        }
        boolean ret;
        try {
            ret = mCasInterface.startJniRecv();
        } catch (RemoteException e) {
            CASLog.e(TAG, "filed to call startJniRecv");
            ret = false;
        }
        return ret;
    }

    public void stopJniRecv() {
        if (mCasInterface == null) {
            return;
        }
        try {
            mCasInterface.stopJniRecv();
        } catch (RemoteException e) {
            CASLog.e(TAG, "filed to call stopJniRecv");
        }
    }

    public void mute(boolean isMute) {
        if (mCasInterface == null) {
            return;
        }
        try {
            mCasInterface.mute(isMute);
        } catch (RemoteException e) {
            CASLog.e(TAG, "failed to mute.");
        }
    }

    public void sendDataToCloudApp(byte[] data) {
        if (mCasInterface == null) {
            return;
        }
        try {
            mCasInterface.sendData(CHANNEL, data);
        } catch (RemoteException e) {
            CASLog.e(TAG, "failed to send data to cloud app.");
        }
    }

    public void sendDataToVirtualDevice(byte devType, byte[] data) {
        if (mCasInterface == null) {
            return;
        }
        try {
            mCasInterface.sendData(devType, data);
        } catch (RemoteException e) {
            CASLog.e(TAG, "failed to send data to virtual device.");
        }
    }

    public void sendDataToIme(byte[] data) {
        if (mCasInterface == null) {
            return;
        }
        try {
            mCasInterface.sendData(IMEDATA, data);
        } catch (RemoteException e) {
            CASLog.e(TAG, "failed to send data to virtual device.");
        }
    }

}
